#ifndef __WRITE_AND_TRUNC_H__
#define __WRITE_AND_TRUNC_H__

#include <stdarg.h>

static inline void write_and_trunc(char *file, int keep_line, const char *fmt, ...)
{
    char line[4096], tmp_file[512];
    int count = 0, i, sub;
    FILE *fp = fopen(file, "a"); if (fp == NULL) { LOGERR("fail to fopen(%s, a)[%m]\n", file); return; }

    va_list va; va_start(va, fmt); vsprintf(line, fmt, va); va_end(va);
    fputs(line, fp); fputs("\n", fp); fclose(fp);

    fp = fopen(file, "r"); if (fp == NULL) { LOGERR("fail to fopen(%s, r)[%m]\n", file); return; }
    for (;;) {
        if (fgets(line, sizeof(line), fp) == NULL) break;
        count++;
    }
    if (count <= keep_line) { fclose(fp); return; }

    sub = count - keep_line;
    rewind(fp); for (i = 0; i < sub; i++) fgets(line, sizeof(line), fp);

    sprintf(tmp_file, "%s.tmp", file);
    FILE *tmp_fp = fopen(tmp_file, "w"); if (tmp_fp == NULL) { LOGERR("fail to fopen(%s, w)\n", tmp_file); fclose(fp); return; }
    for (;;) {
        if (fgets(line, sizeof(line), fp) == NULL) break;
        fputs(line, tmp_fp);
    }

    fclose(tmp_fp); fclose(fp); unlink(file);
    if (rename(tmp_file, file)) { LOGERR("rename(%s, %s) error[%m]\n", tmp_file, file); return; }
}

#endif
